import 'dart:convert';

import 'package:backend.core/core/domain/entities/access_token_claim.dart';
import 'package:shelf/shelf.dart';

const _kRequestAccessTokenClaimKey = 'access_token_claim';

Future<Map<String, dynamic>> parseJsonRequestBody({
  required Request request,
}) async {
  final bodyString = await request.readAsString();

  try {
    return jsonDecode(bodyString);
  } catch(_) {
    return const {};
  }
}

String? extractAccessTokenData({
  required Request request,
}) {
  final authorizationHeader = request.headers['Authorization'];

  if (authorizationHeader == null || !authorizationHeader.startsWith('Bearer ')) {
    return null;
  }

  final accessTokenData = authorizationHeader.replaceFirst('Bearer ', '');

  if (accessTokenData.isEmpty) {
    return null;
  }

  return accessTokenData;
}

AccessTokenClaim extractAccessTokenClaim({
  required Request request,
}) {
  return maybeExtractAccessTokenClaim(
    request: request,
  )!;
}

AccessTokenClaim? maybeExtractAccessTokenClaim({
  required Request request,
}) {
  return request.context[_kRequestAccessTokenClaimKey] as AccessTokenClaim?;
}

Request setAccessTokenClaim({
  required Request request,
  required AccessTokenClaim accessTokenClaim,
}) {
  return request.change(
    context: {
      _kRequestAccessTokenClaimKey: accessTokenClaim,
    },
  );
}

String extractIpAddress({
  required Request request,
}) {
  return request.headers['x-real-ip'] as String;
}
